package kalender.backend;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;


public class Event  {
	private int eid;
	private Luser uid;
	private boolean pubshare;
	private EventType etype;
	private String e_desc;
	private java.util.Date start_ts;
	private java.util.Date stop_ts;
	
	public int getEid() { return eid; }
	public void setEid(int e) { eid = e; }
	
	public Luser getUid() { return uid; }
	public void setUid(Luser u) { uid = u; }
	
	public boolean getPubshare() { return pubshare; }
	public void setPubshare(boolean pub) { pubshare = pub; }
	
	public EventType getEtype() { return etype; }
	public void setEtype(EventType et) { etype = et; }
	
	public String getE_desc() { return e_desc; } 
	public void setE_desc(String e) { e_desc = e; }
	
	public java.util.Date getStart_ts() { return start_ts; }
	public void setStart_ts(java.util.Date ts) { start_ts = ts; }
	
	public java.util.Date getStop_ts() { return stop_ts; }
	public void setStop_ts(java.util.Date ts) { stop_ts = ts; }
	
	public String toString() { return "eid: " + eid + " uid: " + uid + " pubshare: " + pubshare + " etype " + etype + " e_desc: " + e_desc + " start_ts:  " + start_ts + " stop_ts: " + stop_ts; }
	
	public static Event find(int eid) throws BackendException {
		Connection conn = DatabaseManager.getConnection();
		try {
			PreparedStatement ps = conn.prepareStatement("select * from event where eid = ?");
			ps.setInt(1, eid);
			ResultSet rs = ps.executeQuery();
			SQLWarning warning = ps.getWarnings();
			DatabaseManager.printWarning(warning);
			SQLWarning warn2 = rs.getWarnings();
			DatabaseManager.printWarning(warn2);
			
			if (rs.next()) {
				Event e = new Event();
				e.eid = eid;
				e.e_desc = rs.getString("e_desc");
				e.pubshare = rs.getBoolean("pubshare");
				
				// Get the date from db in as java.sql.Timestamp and convert them to java.util.Date
				java.sql.Timestamp start = rs.getTimestamp("start_ts");
				java.sql.Timestamp stop = rs.getTimestamp("stop_ts");
				
				e.start_ts = toDate(start);
				e.stop_ts = toDate(stop);

				int et = rs.getInt("etype");
				e.etype = EventType.find(et);
				
				int usr = rs.getInt("uid");
				e.uid = Luser.find(usr);
				
				return e;
			} else {
				return null;
			}
		} catch (SQLException e) {
			DatabaseManager.printException(e);
			throw new BackendException("Databasfel. Var god försök igen.", e);
		}
	}
	
	public static List<Event> findAll() throws BackendException {
		Connection conn = DatabaseManager.getConnection();
		try {
			PreparedStatement ps = conn.prepareStatement("select * from event order by start_ts");
			ResultSet rs = ps.executeQuery();
			SQLWarning warning = ps.getWarnings();
			DatabaseManager.printWarning(warning);
			SQLWarning warn2 = rs.getWarnings();
			DatabaseManager.printWarning(warn2);
			
			ArrayList<Event> events = new ArrayList<Event>();
			while (rs.next()) {
				Event e = new Event();
				e.eid = rs.getInt("eid");
				e.e_desc = rs.getString("e_desc");
				e.pubshare = rs.getBoolean("pubshare");
				
				// Get the date from db in as java.sql.Timestamp and convert them to java.util.Date
				java.sql.Timestamp start = rs.getTimestamp("start_ts");
				java.sql.Timestamp stop = rs.getTimestamp("stop_ts");
				
				e.start_ts = toDate(start);
				e.stop_ts = toDate(stop);
				
				int et = rs.getInt("etype");
				e.etype = EventType.find(et);
				
				int usr = rs.getInt("uid");
				e.uid = Luser.find(usr);
				
				events.add(e);
			}
			return events;
		} catch (SQLException e) {
			DatabaseManager.printException(e);
			throw new BackendException("Databasfel. Var god försök igen.", e);
		}
	}

	public static List<Event> findPublicByDate(java.util.Date start, java.util.Date stop) throws BackendException {
		Connection conn = DatabaseManager.getConnection();
		try {
			PreparedStatement ps = conn.prepareStatement("select * from event where start_ts between ? and ? and pubshare = TRUE order by start_ts");
			ps.setTimestamp(1, new java.sql.Timestamp(start.getTime()));
			ps.setTimestamp(2, new java.sql.Timestamp(stop.getTime()));
			ResultSet rs = ps.executeQuery();
			SQLWarning warning = ps.getWarnings();
			DatabaseManager.printWarning(warning);
			SQLWarning warn2 = rs.getWarnings();
			DatabaseManager.printWarning(warn2);
			
			List<Event> events = new ArrayList<Event>();
			while (rs.next()) {
				Event e = new Event();
				e.eid = rs.getInt("eid");
				e.e_desc = rs.getString("e_desc");
				e.pubshare = rs.getBoolean("pubshare");
				
				// Get the date from db in as java.sql.Timestamp and convert them to java.util.Date
				java.sql.Timestamp start1 = rs.getTimestamp("start_ts");
				java.sql.Timestamp stop2 = rs.getTimestamp("stop_ts");
				
				e.start_ts = toDate(start1);
				e.stop_ts = toDate(stop2);
				
				int et = rs.getInt("etype");
				e.etype = EventType.find(et);
				
				int usr = rs.getInt("uid");
				e.uid = Luser.find(usr);
				
				events.add(e);
			}
			return events;
		} catch (SQLException e) {
			DatabaseManager.printException(e);
			throw new BackendException("Databasfel. Var god försök igen.", e);
		}
	}
	
	public static List<Event> findByUserAndDate(Luser user, java.util.Date start, java.util.Date stop) throws BackendException {
		Connection conn = DatabaseManager.getConnection();
		try {
			PreparedStatement ps = conn.prepareStatement("select * from event where uid = ? and start_ts between ? and ? order by start_ts");
			ps.setInt(1, user.getUid());
			ps.setTimestamp(2, new java.sql.Timestamp(start.getTime()));
			ps.setTimestamp(3, new java.sql.Timestamp(stop.getTime()));
			ResultSet rs = ps.executeQuery();
			SQLWarning warning = ps.getWarnings();
			DatabaseManager.printWarning(warning);
			SQLWarning warn2 = rs.getWarnings();
			DatabaseManager.printWarning(warn2);
			
			List<Event> events = new ArrayList<Event>();
			while (rs.next()) {
				Event e = new Event();
				e.eid = rs.getInt("eid");
				e.e_desc = rs.getString("e_desc");
				e.pubshare = rs.getBoolean("pubshare");
				
				// Get the date from db in as java.sql.Timestamp and convert them to java.util.Date
				java.sql.Timestamp start1 = rs.getTimestamp("start_ts");
				java.sql.Timestamp stop2 = rs.getTimestamp("stop_ts");
				
				e.start_ts = toDate(start1);
				e.stop_ts = toDate(stop2);
				
				int et = rs.getInt("etype");
				e.etype = EventType.find(et);
				
				int usr = rs.getInt("uid");
				e.uid = Luser.find(usr);
				
				events.add(e);
			}
			return events;
		} catch (SQLException e) {
			DatabaseManager.printException(e);
			throw new BackendException("Databasfel. Var god försök igen.", e);
		}
	}

        public static List<Event> findByUser(Luser user) throws BackendException {
		Connection conn = DatabaseManager.getConnection();
		try {
			PreparedStatement ps = conn.prepareStatement("select * from event where uid = ? order by start_ts");
			ps.setInt(1, user.getUid());
			ResultSet rs = ps.executeQuery();
			SQLWarning warning = ps.getWarnings();
			DatabaseManager.printWarning(warning);
			SQLWarning warn2 = rs.getWarnings();
			DatabaseManager.printWarning(warn2);

			List<Event> events = new ArrayList<Event>();
			while (rs.next()) {
				Event e = new Event();
				e.eid = rs.getInt("eid");
				e.e_desc = rs.getString("e_desc");
				e.pubshare = rs.getBoolean("pubshare");

				// Get the date from db in as java.sql.Timestamp and convert them to java.util.Date
				java.sql.Timestamp start1 = rs.getTimestamp("start_ts");
				java.sql.Timestamp stop2 = rs.getTimestamp("stop_ts");

				e.start_ts = toDate(start1);
				e.stop_ts = toDate(stop2);

				int et = rs.getInt("etype");
				e.etype = EventType.find(et);

				int usr = rs.getInt("uid");
				e.uid = Luser.find(usr);

				events.add(e);
			}
			return events;
		} catch (SQLException e) {
			DatabaseManager.printException(e);
			throw new BackendException("Databasfel. Var god försök igen.", e);
		}
	}
	
	public void saveNew() throws BackendException {
		Connection conn = DatabaseManager.getConnection();
		try {
			PreparedStatement ps = conn.prepareStatement("insert into event (e_desc, start_ts, stop_ts, etype, uid, pubshare) values(?, ?, ?, ?, ?, ?)", Statement.RETURN_GENERATED_KEYS);
			
			ps.setString(1, e_desc);
					
			ps.setTimestamp(2, new java.sql.Timestamp(start_ts.getTime()));
			ps.setTimestamp(3, new java.sql.Timestamp(stop_ts.getTime()));
			
			ps.setInt(4, etype.getEtype());
			ps.setInt(5, uid.getUid());
			ps.setBoolean(6, pubshare);
			ps.executeUpdate();
			SQLWarning warning = ps.getWarnings();
			DatabaseManager.printWarning(warning);
			ResultSet keys = ps.getGeneratedKeys();
			keys.next();
			eid = keys.getInt(1);
		} catch (SQLException e) {
			DatabaseManager.printException(e);
			throw new BackendException("Databasfel. Var god försök igen.", e);
		}
	}
	
	public void saveUpdate() throws BackendException {
		Connection conn = DatabaseManager.getConnection();
		try {
			PreparedStatement ps = conn.prepareStatement("update event set etype = ?, e_desc = ?, start_ts = ?, stop_ts = ?, uid = ?, pubshare = ? where eid = ?");
			ps.setInt(1, etype.getEtype());
			ps.setString(2, e_desc);
						
			ps.setTimestamp(3, new java.sql.Timestamp(start_ts.getTime()));
			ps.setTimestamp(4, new java.sql.Timestamp(stop_ts.getTime()));
			
			ps.setInt(5, uid.getUid());
			ps.setBoolean(6, pubshare);
			
			ps.setInt(7, eid);
			
			ps.executeUpdate();
			SQLWarning warning = ps.getWarnings();
			DatabaseManager.printWarning(warning);
		} catch (SQLException e) {
			DatabaseManager.printException(e);
			throw new BackendException("Databasfel. Var god försök igen.", e);
		}
	}
	
	public static void delete(int eid) throws BackendException {
		Connection conn = DatabaseManager.getConnection();
		try {
			PreparedStatement ps = conn.prepareStatement("delete from event where eid = ?");
			ps.setInt(1, eid);
			ps.executeUpdate();
			SQLWarning warning = ps.getWarnings();
			DatabaseManager.printWarning(warning);
		} catch (SQLException e) {
			DatabaseManager.printException(e);
			throw new BackendException("Databasfel. Var god försök igen.", e);
		}
	}
	
	private static java.util.Date toDate(java.sql.Timestamp timestamp) {
	    long milliseconds = timestamp.getTime() + (timestamp.getNanos() / 1000000);
	    return new java.util.Date(milliseconds);
	}
}
